package top.healthylife.pangwa.server;/*
 *@Author GaoZeXi
 *@Created time 2020/5/6 18:53
 *@Description:
 * Step by Step  and Stand on,  You Are The Best Investment!!!
 */

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@EnableScheduling
public class PangWaController {
    private Logger logger = LoggerFactory.getLogger(PangWaController.class);

    /**
     * 保存服务数据
     */
    private Map<String, Object> dataMap = new HashMap<>(16);
    /**
     * 保存心跳信息
     */
    private Map<String, Object> heartbeatMap = new HashMap<>(16);


    @RequestMapping("/register")
    public void register(@RequestBody Map<String, Object> args, HttpServletRequest request) {
        String serviceName = (String) args.get("serviceName");
        if (serviceName != null || serviceName.length() != 0) {
            int port = (int) args.get("port");
            String host = request.getRemoteHost();
            dataMap.put(serviceName, host + ":" + port);
            logger.info("Registered Service Info :" + serviceName.toUpperCase() + " host: " + host +
                    " port: " + port);
        }
    }

    @RequestMapping("/dispatch/{serviceName}")
    public String dispatch(@PathVariable("serviceName") String serviceName) {

        logger.info("some application apply for serviceName which named is" + serviceName );
        if (serviceName == null || serviceName.length() == 0) {
            return null;
        } else {
            serviceName = serviceName.toUpperCase();
            if (dataMap.containsKey(serviceName)) {
                String result = (String) dataMap.get(serviceName);
                logger.info("Pull serviceData Success ,now  will  response " + "  data:" + result +"to the client");
                return result;
            } else {
                return null;
            }
        }


    }

    @RequestMapping("/findAll")
    public List<Result> findAll() {
        List<Result> list = new ArrayList<>();
        Set<String> serviceNames = dataMap.keySet();
        int i = 1;
        for (String serviceName : serviceNames) {
            Result result = new Result();
            result.setId(i++);
            result.setServiceName(serviceName);
            result.setHostPort((String) dataMap.get(serviceName));
            result.setStatus("UP");
            list.add(result);
        }
        return list;
    }

    @RequestMapping("/ping/{serviceName}")
    public String pingPong(@PathVariable String serviceName) {
        if (serviceName == null || serviceName.length() == 0) {
            return null;
        } else {
            serviceName = serviceName.toUpperCase();
            if(dataMap.keySet().contains(serviceName)){
                String response = "{\"client\":\""+serviceName+"-ping\",\"server\": \"pong\"," +
                        "\"result\":\"success\"}";
                logger.info(response);
                //存入心跳信息
                heartbeatMap.put(serviceName, System.currentTimeMillis());
                return response;
            }else{
                String response = "{\"client\":\"null-ping\",\"server\": \"pong\"," +
                        "\"result\":\"failed\"}";
                logger.info(response);
                return response;
            }

        }

    }

    @Scheduled(cron = "* * * * * ?")
    public void cronJob(){
        riskManagement();
    }
    public void riskManagement() {
        if(dataMap.keySet().size()!=0){
            logger.info("Number of registered services =  " + dataMap.keySet().size());
            for (String serviceName : dataMap.keySet()) {
                long saveTime = (long) heartbeatMap.get(serviceName);
                double time  = (System.currentTimeMillis() - saveTime) / 1000;
                //断开连接两次后
                if (time>6) {
                    logger.warn(serviceName+"The service has not responded for a long time and " +
                            "has been unregistered ");
                    dataMap.remove(serviceName);
                }
            }
        }else{
            logger.info("No service registered...");
        }

    }
}
